package winsvc

import (
	"fmt"
	"os"
	"time"

	"golang.org/x/sys/windows/svc"
	"golang.org/x/sys/windows/svc/eventlog"
	"golang.org/x/sys/windows/svc/mgr"
)

type method int

const (
	methodInstall method = iota
	methodUninstall
	methodStart
	methodStop
	methodRestart
)

// handleServiceCommand 处理服务控制命令
func (s *serviceImpl) handleServiceCommand(method method) {
	switch method {
	case methodInstall:
		if err := s.handleInstall(); err != nil {
			s.MessageBox("安装服务失败", err.Error(), MB_OK|MB_ICONERROR)
			return
		}
		s.MessageBox("安装服务成功", "服务已成功安装，正在启动服务...", MB_OK|MB_ICONINFORMATION)

		// 安装成功后尝试启动服务
		if err := s.handleStart(); err != nil {
			s.MessageBox("启动服务失败", err.Error(), MB_OK|MB_ICONERROR)
			return
		}
		s.MessageBox("启动服务成功", "服务已成功启动", MB_OK|MB_ICONINFORMATION)

	case methodUninstall:
		// 卸载前尝试停止服务
		status, statusErr := s.GetServiceStatus()
		if statusErr == nil && status == Running {
			if err := s.handleStop(); err != nil {
				s.MessageBox("停止服务失败", err.Error(), MB_OK|MB_ICONERROR)
				return
			}
		}

		if err := s.handleUninstall(); err != nil {
			s.MessageBox("卸载服务失败", err.Error(), MB_OK|MB_ICONERROR)
			return
		}
		s.MessageBox("卸载服务成功", "服务已成功卸载", MB_OK|MB_ICONINFORMATION)

	case methodStart:

		if err := s.handleStart(); err != nil {
			s.MessageBox("启动服务失败", err.Error(), MB_OK|MB_ICONERROR)
			return
		}
		s.MessageBox("启动服务成功", "服务已成功启动", MB_OK|MB_ICONINFORMATION)

	case methodStop:

		if err := s.handleStop(); err != nil {
			s.MessageBox("停止服务失败", err.Error(), MB_OK|MB_ICONERROR)
			return
		}
		s.MessageBox("停止服务成功", "服务已成功停止", MB_OK|MB_ICONINFORMATION)

	case methodRestart:
		if err := s.handleRestart(); err != nil {
			s.MessageBox("重启服务失败", err.Error(), MB_OK|MB_ICONERROR)
			return
		}
		s.MessageBox("重启服务成功", "服务已成功重启", MB_OK|MB_ICONINFORMATION)
	}
}

func (s *serviceImpl) handleInstall() error {
	// 检查服务是否已经存在
	if s.IsServiceExist() {
		return fmt.Errorf(fmt.Sprintf("服务 %s 已存在", s.config.ServiceName))
	}

	// 获取当前可执行文件路径
	exePath, err := os.Executable()
	if err != nil {
		return fmt.Errorf(fmt.Sprintf("无法获取可执行文件路径: %v", err))
	}

	// 连接服务管理器
	m, err := mgr.Connect()
	if err != nil {
		return fmt.Errorf(fmt.Sprintf("无法连接到服务管理器: %v", err))
	}
	defer m.Disconnect()

	// 创建服务
	service, err := m.CreateService(s.config.ServiceName, exePath, mgr.Config{
		DisplayName: s.config.ServiceDisplayName,
		Description: s.config.ServiceDescription,
		StartType:   mgr.StartAutomatic,
	})
	if err != nil {
		return fmt.Errorf(fmt.Sprintf("无法创建服务: %v", err))
	}
	defer service.Close()

	// 设置服务恢复操作
	err = service.SetRecoveryActions([]mgr.RecoveryAction{
		{Type: mgr.ServiceRestart, Delay: 5 * time.Second},
		{Type: mgr.ServiceRestart, Delay: 10 * time.Second},
		{Type: mgr.ServiceRestart, Delay: 15 * time.Second},
	}, uint32(60)) // 这里需要使用 uint32 类型的秒数
	if err != nil {
		return fmt.Errorf(fmt.Sprintf("无法设置服务恢复操作: %v", err))
	}

	// 创建事件日志
	err = eventlog.InstallAsEventCreate(s.config.ServiceName, eventlog.Error|eventlog.Warning|eventlog.Info)
	if err != nil {
		// 如果事件日志创建失败，尝试删除服务
		_ = service.Delete()
		return fmt.Errorf(fmt.Sprintf("无法设置事件日志: %v", err))
	}
	return nil
}

func (s *serviceImpl) handleUninstall() error {
	// 检查服务是否存在
	if !s.IsServiceExist() {
		return fmt.Errorf("服务 %s 不存在", s.config.ServiceName)
	}

	// 连接服务管理器
	m, err := mgr.Connect()
	if err != nil {
		return fmt.Errorf("无法连接到服务管理器: %v", err)
	}
	defer m.Disconnect()

	// 打开服务
	service, err := m.OpenService(s.config.ServiceName)
	if err != nil {
		return fmt.Errorf("无法打开服务: %v", err)
	}
	defer service.Close()

	// 删除服务
	err = service.Delete()
	if err != nil {
		return fmt.Errorf("无法删除服务: %v", err)
	}

	// 删除事件日志
	err = eventlog.Remove(s.config.ServiceName)
	if err != nil {
		return fmt.Errorf("无法删除事件日志: %v", err)
	}

	return nil
}

func (s *serviceImpl) handleStart() error {
	// 检查服务是否存在
	if !s.IsServiceExist() {
		return fmt.Errorf("服务 %s 不存在", s.config.ServiceName)
	}

	// 获取服务状态
	status, err := s.GetServiceStatus()
	if err != nil {
		return err
	}

	// 如果服务已经在运行，直接返回
	if status == Running {
		return fmt.Errorf("服务 %s 已经在运行中", s.config.ServiceName)
	}

	// 连接服务管理器
	m, err := mgr.Connect()
	if err != nil {
		return fmt.Errorf("无法连接到服务管理器: %v", err)
	}
	defer m.Disconnect()

	// 打开服务
	service, err := m.OpenService(s.config.ServiceName)
	if err != nil {
		return fmt.Errorf("无法打开服务: %v", err)
	}
	defer service.Close()

	// 启动服务
	err = service.Start()
	if err != nil {
		return fmt.Errorf("无法启动服务: %v", err)
	}

	return nil
}

func (s *serviceImpl) handleStop() error {
	// 检查服务是否存在
	if !s.IsServiceExist() {
		return fmt.Errorf("服务 %s 不存在", s.config.ServiceName)
	}

	// 获取服务状态
	status, err := s.GetServiceStatus()
	if err != nil {
		return err
	}

	// 如果服务已经停止，直接返回
	if status == Stopped {
		return fmt.Errorf("服务 %s 已经停止", s.config.ServiceName)
	}

	// 连接服务管理器
	m, err := mgr.Connect()
	if err != nil {
		return fmt.Errorf("无法连接到服务管理器: %v", err)
	}
	defer m.Disconnect()

	// 打开服务
	service, err := m.OpenService(s.config.ServiceName)
	if err != nil {
		return fmt.Errorf("无法打开服务: %v", err)
	}
	defer service.Close()

	// 构建服务状态请求
	timeout := 30 * time.Second
	statusInfo, err := service.Control(svc.Stop)
	if err != nil {
		return fmt.Errorf("无法发送停止命令: %v", err)
	}

	// 等待服务停止
	startTime := time.Now()
	for statusInfo.State != svc.Stopped {
		if time.Since(startTime) > timeout {
			return fmt.Errorf("等待服务停止超时")
		}
		time.Sleep(300 * time.Millisecond)
		statusInfo, err = service.Query()
		if err != nil {
			return fmt.Errorf("无法查询服务状态: %v", err)
		}
	}

	return nil
}

func (s *serviceImpl) handleRestart() error {
	// 检查服务是否存在
	if !s.IsServiceExist() {
		return fmt.Errorf("服务 %s 不存在", s.config.ServiceName)
	}

	// 获取服务状态
	status, err := s.GetServiceStatus()
	if err != nil {
		return err
	}

	// 如果服务正在运行，先停止
	if status == Running {
		err = s.handleStop()
		if err != nil {
			return fmt.Errorf("无法停止服务: %v", err)
		}
	}

	// 启动服务
	err = s.handleStart()
	if err != nil {
		return fmt.Errorf("无法启动服务: %v", err)
	}

	return nil
}
